\section*{Appendix}
\label{sec:append}

We use the trivial.c in test/micro directory to show the way our SLP
implementation works.

\lstset{language=C}
\begin{lstlisting}
int main(int argc, char** argv) {
  int a=argc;
  int b=argc+1;
  int c=argc-1;
  int d=argc*2;
  //Below is the section for SLP
  int o1=a+z[0];
  int o2=b+z[1];
  int o3=c+z[2];
  int o4=d+z[3];
  //The final result
  return o1+o2+o3+o4;
}
\end{lstlisting}

The input LLVM IR for SLP.
\lstset{language=C}
\begin{lstlisting}
define i32 @main(i32 %argc, i8** %argv) nounwind uwtable {
entry:
  %add = add nsw i32 %argc, 1
  %sub = sub nsw i32 %argc, 1
  %mul = mul nsw i32 %argc, 2
  %0 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 0), align 4
  %add1 = add nsw i32 %argc, %0
  %1 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 1), align 4
  %add2 = add nsw i32 %add, %1
  %2 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 2), align 4
  %add3 = add nsw i32 %sub, %2
  %3 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 3), align 4
  %add4 = add nsw i32 %mul, %3
  %add5 = add nsw i32 %add1, %add2
  %add6 = add nsw i32 %add5, %add3
  %add7 = add nsw i32 %add6, %add4
  ret i32 %add7
}
\end{lstlisting}

The isomorphic statements packs identified because of adjacent memory access.
\lstset{language=C}
\begin{lstlisting}
[PackSet Size:3]
{
[Set]0
  %0 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 0), align 4
  %1 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 1), align 4
[Set]1
  %1 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 1), align 4
  %2 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 2), align 4
[Set]2
  %2 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 2), align 4
  %3 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 3), align 4
}
\end{lstlisting}

The isomorphic statements packs identified after extending packs.
\lstset{language=C}
\begin{lstlisting}
[PackSet Size:6]
{
[Set]0
  %0 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 0), align 4
  %1 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 1), align 4
[Set]1
  %add1 = add nsw i32 %argc, %0
  %add2 = add nsw i32 %add, %1
[Set]2
  %1 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 1), align 4
  %2 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 2), align 4
[Set]3
  %add2 = add nsw i32 %add, %1
  %add3 = add nsw i32 %sub, %2
[Set]4
  %2 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 2), align 4
  %3 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 3), align 4
[Set]5
  %add3 = add nsw i32 %sub, %2
  %add4 = add nsw i32 %mul, %3
}
\end{lstlisting}

The isomorphic statements packs after combine packs.
\lstset{language=C}
\begin{lstlisting}
[PackSet Size:2]
{
[Set]0
  %0 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 0), align 4
  %1 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 1), align 4
  %2 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 2), align 4
  %3 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 3), align 4
[Set]1
  %add1 = add nsw i32 %argc, %0
  %add2 = add nsw i32 %add, %1
  %add3 = add nsw i32 %sub, %2
  %add4 = add nsw i32 %mul, %3
}
\end{lstlisting}

The LLVM code for the main body after code scheduling.
\lstset{language=C}
\begin{lstlisting}
entry:
  %add = add nsw i32 %argc, 1
  %sub = sub nsw i32 %argc, 1
  %mul = mul nsw i32 %argc, 2
  %0 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 0), align 4
  %1 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 1), align 4
  %2 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 2), align 4
  %3 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 3), align 4
  %add1 = add nsw i32 %argc, %0
  %add2 = add nsw i32 %add, %1
  %add3 = add nsw i32 %sub, %2
  %add4 = add nsw i32 %mul, %3
  %add5 = add nsw i32 %add1, %add2
  %add6 = add nsw i32 %add5, %add3
  %add7 = add nsw i32 %add6, %add4
  ret i32 %add7
\end{lstlisting}

The LLVM code for the main body after code emitting. Note there are some
redundant statements, which will be removed by instruction combine and dead code
elimination.
\lstset{language=C}
\begin{lstlisting}
entry:
  %add = add nsw i32 %argc, 1
  %sub = sub nsw i32 %argc, 1
  %mul = mul nsw i32 %argc, 2
  %0 = load <4 x i32>* bitcast ([4 x i32]* @z to <4 x i32>*), align 4
  %1 = extractelement <4 x i32> %0, i32 0
  %2 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 0), align 4
  %3 = extractelement <4 x i32> %0, i32 1
  %4 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 1), align 4
  %5 = extractelement <4 x i32> %0, i32 2
  %6 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 2), align 4
  %7 = extractelement <4 x i32> %0, i32 3
  %8 = load i32* getelementptr inbounds ([4 x i32]* @z, i32 0, i64 3), align 4
  %9 = insertelement <4 x i32> undef, i32 %argc, i32 0
  %10 = insertelement <4 x i32> %9, i32 %add, i32 1
  %11 = insertelement <4 x i32> %10, i32 %sub, i32 2
  %12 = insertelement <4 x i32> %11, i32 %mul, i32 3
  %13 = insertelement <4 x i32> undef, i32 %1, i32 0
  %14 = insertelement <4 x i32> %13, i32 %3, i32 1
  %15 = insertelement <4 x i32> %14, i32 %5, i32 2
  %16 = insertelement <4 x i32> %15, i32 %7, i32 3
  %17 = add nsw <4 x i32> %12, %16
  %18 = extractelement <4 x i32> %17, i32 0
  %add1 = add nsw i32 %argc, %1
  %19 = extractelement <4 x i32> %17, i32 1
  %add2 = add nsw i32 %add, %3
  %20 = extractelement <4 x i32> %17, i32 2
  %add3 = add nsw i32 %sub, %5
  %21 = extractelement <4 x i32> %17, i32 3
  %add4 = add nsw i32 %mul, %7
  %add5 = add nsw i32 %18, %19
  %add6 = add nsw i32 %add5, %20
  %add7 = add nsw i32 %add6, %21
  ret i32 %add7
\end{lstlisting}

The final LLVM code for the main body.
\lstset{language=C}
\begin{lstlisting}
define i32 @main(i32 %argc, i8** %argv) nounwind uwtable {
entry:
  %add = add nsw i32 %argc, 1
  %sub = add nsw i32 %argc, -1
  %mul = shl nsw i32 %argc, 1
  %0 = load <4 x i32>* bitcast ([4 x i32]* @z to <4 x i32>*), align 16
  %1 = insertelement <4 x i32> undef, i32 %argc, i32 0
  %2 = insertelement <4 x i32> %1, i32 %add, i32 1
  %3 = insertelement <4 x i32> %2, i32 %sub, i32 2
  %4 = insertelement <4 x i32> %3, i32 %mul, i32 3
  %5 = add nsw <4 x i32> %4, %0
  %6 = extractelement <4 x i32> %5, i32 0
  %7 = extractelement <4 x i32> %5, i32 1
  %8 = extractelement <4 x i32> %5, i32 2
  %9 = extractelement <4 x i32> %5, i32 3
  %add5 = add nsw i32 %6, %7
  %add6 = add nsw i32 %add5, %8
  %add7 = add nsw i32 %add6, %9
  ret i32 %add7
}
\end{lstlisting}
